package org.alis.rpc.common.paap;

import org.alis.rpc.common.paap.constant.Constants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

import java.util.Map;

/**
 * @author lc
 * @version v1.0.0
 * @date 2020/8/28 11:31
 * @className x.class
 */
public class AppConfigContext implements BeanFactoryPostProcessor {

    private static Log logger = LogFactory.getLog(AppConfigContext.class);

    public static Configurator getConfigurator() {
        return ContextKeeper.getConfigurator();
    }


    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        try {
            Configurator configurator = (Configurator) beanFactory.getBean(Constants.APPCONFIG_SDK_BEAN_Configurator);
            ContextKeeper.setConfigurator(configurator);
        } catch (NoSuchBeanDefinitionException e) {
            if (logger.isWarnEnabled()) {
                logger.warn(e.getMessage());
            }
        }



    }

    @SuppressWarnings("rawtypes")
    private PropertyPlaceholderConfigurer getPropertyConfigurer(ConfigurableListableBeanFactory beanFactory) {
        Map propertyPlaceholderConfigurers = beanFactory.getBeansOfType(org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.class);
        if (propertyPlaceholderConfigurers.isEmpty()) {
            // 没有在 spring 中配置 org.springframework.beans.factory.config.PropertyPlaceholderConfigurer 类或者它的子类。
            // 现阶段这种情况应该是不会发生滴。
            return null;
        }
        if (propertyPlaceholderConfigurers.get(Constants.APPCONFIG_SDK_BEAN_PropertyPlaceholderConfigurer) != null) {
            // propertyConfigurer 这个 bean 在 sdk 中的 spring-appconfig.xml 中声明了，如果客户端在web.xml中引用了或者在spring的配置文件中引用了，使用这个.
            return (PropertyPlaceholderConfigurer) propertyPlaceholderConfigurers.get(Constants.APPCONFIG_SDK_BEAN_PropertyPlaceholderConfigurer);
        }
        // 客户端没有引用 sdk 中的 spring-appconfig.xml。但是想通过 ConfigUtils 中的 getLocalConfig 方法来获取 properties 文件中的值。返回客户端自己声明的
        // 如果声明了多个，返回第一个。
        return (PropertyPlaceholderConfigurer) propertyPlaceholderConfigurers.values().toArray()[0];
    }
}

final class ContextKeeper {

    private static Configurator configurator;
    private static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer;

    private ContextKeeper() {
        throw new IllegalStateException("Utility class");
    }

    static Configurator getConfigurator() {
        return configurator;
    }

    static void setConfigurator(Configurator configurator) {
        ContextKeeper.configurator = configurator;
    }

    static PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer() {
        return propertyPlaceholderConfigurer;
    }

    static void setPropertyPlaceholderConfigurer(PropertyPlaceholderConfigurer propertyPlaceholderConfigurer) {
        ContextKeeper.propertyPlaceholderConfigurer = propertyPlaceholderConfigurer;
    }

}
